using System.Collections;
using System.IO;
using System.Net.Mime;
using SimpleJSON;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;

namespace Gj
{
    public class LocalImageHelper : NodeHelper
    {
        public Color disableColor = new(255, 255, 255, 0.4f);
        public Color originColor = new(255, 255, 255);
        public Sprite disableSprite;
        public Sprite originSprite;
        public bool raw;
        public bool bindKey;
        public Sprite emptySprite;
        public Texture2D emptyTexture;
        public string format;

        [SelectRef(UIKey.DATA_KEY)] public SelectKey disabledKey;
        public bool invert;
        private Image _Image;
        private RawImage _RawImage;
        protected bool disabled;
        private string path;
        private bool load;

        private Image Image
        {
            get
            {
                if (_Image == null) _Image = GetComponent<Image>();
                return _Image;
            }
        }

        private RawImage RawImage
        {
            get
            {
                if (_RawImage == null) _RawImage = GetComponent<RawImage>();
                return _RawImage;
            }
        }

        protected override BindDataType bindDataType => BindDataType.String;

        public override void SetData(JSONObject json)
        {
            if (!disabledKey.IsEmpty())
            {
                disabled = invert ? !disabledKey.Get(json).AsBool : disabledKey.Get(json).AsBool;
                if (disabled)
                    Disabled();
                else
                    Enabled();
            }

            base.SetData(json);
            if (bindKey) BindData(key);
        }

        protected override void BindData(string s)
        {
            if (StringTools.IsEmpty(s))
            {
                SetEmpty();
            }
            else
            {
                if (path == s) return;
                path = s;
                load = true;
            }
            if (!gameObject.activeSelf) gameObject.SetActive(true);
        }

        protected override void BindData(float f)
        {
            Image.fillAmount = f;
        }

        protected override void BindData(bool b)
        {
            if (b)
                Enabled();
            else
                Disabled();
        }
        
        IEnumerator LoadPath(string path)
        {
            var filePath = GetCachedFilePath(path);
            if(File.Exists(filePath))
            {
                yield return LoadFromFileCache(filePath);
            }
            else
            {
                SetEmpty();
            }
        }
        
        IEnumerator LoadFromFileCache(string filePath)
        {
            byte[] fileData = File.ReadAllBytes(filePath);
            Texture2D texture = new Texture2D(2, 2);
            texture.LoadImage(fileData); // 自动识别图片格式
            Refresh(texture);
            yield break;
        }
        
        string GetCachedFilePath(string id)
        {
            string uri = Application.persistentDataPath;
            return string.Format(format, uri, id);
        }

        private void SetEmpty()
        {
            if (raw)
            {
                RawImage.texture = emptyTexture;
            }
            else
            {
                Image.sprite = emptySprite;
            }
        }

        private void Refresh(Texture2D texture2D)
        {
            if (raw)
            {
                RawImage.texture = texture2D;
            }
            else
            {
                Sprite sprite = Sprite.Create(
                    texture2D,
                    new Rect(0, 0, texture2D.width, texture2D.height),
                    new Vector2(0.5f, 0.5f)
                );
                Image.sprite = sprite;
            }
        }
        
        bool IsImageVisible(Image image)
        {
            RectTransform rectTransform = image.rectTransform;
            Vector3[] corners = new Vector3[4];
            rectTransform.GetWorldCorners(corners); // 获取UI的四个角的世界坐标
    
            // 检查是否有任意一个角在屏幕内
            foreach (Vector3 corner in corners)
            {
                if (corner.x > 0 && corner.x < SystemInput.screenSize.x && corner.y > 0 &&
                    corner.y < SystemInput.screenSize.y)
                {
                    return true;
                }
                // Vector2 screenPoint = Camera.main.WorldToViewportPoint(corner);
                // Debug.LogErrorFormat("{0} {1}", corner, screenPoint);
                // if (screenPoint.x >= 0 && screenPoint.x <= 1 && screenPoint.y >= 0 && screenPoint.y <= 1)
                // {
                //     return true;
                // }
            }
            return false;
        }

        void Update()
        {
            if (raw)
            {
                
            }
            else
            {
                if (load && IsImageVisible(Image))
                {
                    load = false;
                    StartCoroutine(LoadPath(path));
                }
            }
        }

        private void Disabled()
        {
            disabled = true;
            if (raw)
                RawImage.color = disableColor;
            else
                Image.color = disableColor;
            if (disableSprite != null) Image.sprite = disableSprite;
        }

        private void Enabled()
        {
            disabled = false;
            if (raw)
                RawImage.color = originColor;
            else
                Image.color = originColor;
            if (originSprite != null) Image.sprite = originSprite;
        }
    }
}